package com.john.bms.service.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.john.bms.config.jwt.JwtConfiguration;
import com.john.bms.config.redis.RedisStringService;
import com.john.bms.mapper.system.UserInfoMapper;
import com.john.bms.mapper.system.UserMapper;
import com.john.bms.model.system.LoginModel;
import com.john.bms.model.system.UserVo;
import com.john.bms.model.system.user.SysUser;
import com.john.bms.model.system.user.SysUserInfo;
import com.john.bms.model.system.user.UserPage;
import com.john.bms.utils.Jurisdiction;
import com.john.bms.utils.SnowflakeUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


@Service
public class UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    RedisStringService redisUtils;

    @Resource
    private UserInfoMapper userInfoMapper;

    public String doLogin(LoginModel loginModel) throws Exception {
        UsernamePasswordToken token = new UsernamePasswordToken(loginModel.getUsername(), new SimpleHash("md5", loginModel.getPassword()).toString());
        //获取当前用户对象 subject
        Subject subject = SecurityUtils.getSubject();
        try {
            token.setRememberMe(true);
            //这一步在调用login(token)方法时,MyShiroRealm.doGetAuthenticationInfo()方法中
            subject.login(token);
            if (subject.isAuthenticated()) {
                //返回的token
                SysUser user = userMapper.doLogin(loginModel.getUsername(), new SimpleHash("md5", loginModel.getPassword()).toString());
                String tokenBack = JwtConfiguration.getToken(user.getId());

                return tokenBack;
            } else {
                token.clear();
                return null;
            }
        } catch (UnknownAccountException ue) {
            throw new UnknownAccountException("用户名或密码不正确!");
        } catch (IncorrectCredentialsException ice) {
            throw new IncorrectCredentialsException("用户名或密码错误！");
        } catch (LockedAccountException lae) {
            throw new LockedAccountException("该账号已经被禁用,请联系管理员！");
        } catch (DisabledAccountException dae) {
            throw new DisabledAccountException("该账号未启用,请联系管理员！");
        } catch (Exception e) {
            throw new Exception("系统异常！");
        }

    }

    /**
     * 分页查询
     * page中参数一 当前页
     * page中参数二 页面大小
     * wrapper复杂查询
     *
     * @return
     */
    public PageInfo<UserVo> getPageUserList(UserPage userPage) {
        PageHelper.startPage(userPage.getPageNum(), userPage.getPageSize());
        List<UserVo> userVos = userMapper.selectPageUserList(userPage);
        PageInfo<UserVo> pageInfo = new PageInfo<>(userVos);
        return pageInfo;
    }

    /**
     * 根据id查询单个
     *
     * @param id
     * @return
     */
    public UserVo getUserById(String id) {
        UserVo userVo = userMapper.selectOneUser(id);
        return userVo;
    }

    public boolean updateUserState(String id, int state) {

        return userMapper.updateUserStateById(id, state) == 1 ? true : false;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean addUser(UserVo userVo) throws Exception {
        boolean falg = false;
        //如果填写了邮箱，则验证邮箱是否存在
        if (userVo.getEmail() != null && !"".equals(userVo.getEmail().trim())) {
            int emailCount = userInfoMapper.selectListByEmail(userVo.getEmail().toLowerCase());
            if (emailCount > 0) {
                throw new Exception("该邮箱已存在！");
            }
        }

        if (userVo.getPhone() != null && !"".equals(userVo.getPhone().trim())) {
            int phoneCount = userInfoMapper.selectListByPhone(userVo.getPhone());
            if (phoneCount > 0) {
                throw new Exception("该电话已存在！");
            }
        }

        SysUser sysUser = new SysUser();
        sysUser.setId(SnowflakeUtils.genId() + "");
        sysUser.setUserName(userVo.getUserName());
        sysUser.setPassword(userVo.getPassword());
        //如果用户没有选择角色，则设置成普通用户
        if (userVo.getRId() == 0) {
            sysUser.setRId(4);
        } else {
            sysUser.setRId(userVo.getRId());
        }
        if (userVo.getState() == null) {
            sysUser.setState(1);
        } else {
            sysUser.setState(userVo.getState());
        }
        sysUser.setCreateTime(new Date());
        int u = userMapper.insertUser(sysUser);
        if (sysUser.getId() != null) {
            insertUserInfo(userVo, sysUser.getId());
            //falg = uin == 1 ? true : false;
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(UserVo userVo) {
        //修改用户
        SysUser sysUser = new SysUser();
        sysUser.setId(userVo.getId());
        sysUser.setUserName(userVo.getUserName());
        sysUser.setPassword(userVo.getPassword());
        sysUser.setRId(userVo.getRId());
        sysUser.setUpdateTime(new Date());
        int i = userMapper.updateById(sysUser);
        //修改用户详细
        SysUserInfo userInfo = new SysUserInfo();
        QueryWrapper<SysUserInfo> wrapper = new QueryWrapper<>();
        wrapper
                .eq("u_id", userVo.getId());
        SysUserInfo sysUserInfo = userInfoMapper.selectOne(wrapper);
        if (sysUserInfo != null) {
            userInfo.setInfoId(sysUserInfo.getInfoId());
            userInfo.setGender(userVo.getGender());
            if (userVo.getPhone() != null && !"".equals(userVo.getPhone().trim())) {
                userInfo.setPhone(userVo.getPhone().trim());
            }
            if (userVo.getEmail() != null && !"".equals(userVo.getEmail().trim())) {
                userInfo.setEmail(userVo.getEmail().toLowerCase().trim());
            }
            userInfo.setUId(userVo.getId());
            userInfo.setDateBirth(userVo.getDateBirth());
            userInfo.setUpdateTime(new Date());
            userInfo.setCreateTime(new Date());
            int uin = userInfoMapper.updateById(userInfo);
        } else {
            insertUserInfo(userVo, userVo.getId());
        }
        return i == 1 ? true : false;
    }

    /**
     * 新增用户详细
     *
     * @param userVo
     * @param id
     */
    private void insertUserInfo(UserVo userVo, String id) {
        SysUserInfo userInfo = new SysUserInfo();
        userInfo.setInfoId(SnowflakeUtils.genId() + "");
        userInfo.setGender(userVo.getGender());
        if (userVo.getPhone() != null && !"".equals(userVo.getPhone().trim())) {
            userInfo.setPhone(userVo.getPhone().trim());
        }
        if (userVo.getEmail() != null && !"".equals(userVo.getEmail().trim())) {
            userInfo.setEmail(userVo.getEmail().toLowerCase().trim());
        }
        userInfo.setUId(id);
        userInfo.setDateBirth(userVo.getDateBirth());
        userInfo.setCreateTime(new Date());
        userInfoMapper.insert(userInfo);
    }

    //按用户名条件查询
    public List<SysUser> getUserNamesByMap(HashMap<String, Object> map) {
        //例子
        //map.put("user_name","zgc");
        List<SysUser> sysUsers = userMapper.selectByMap(map);
        return sysUsers;
    }

    public List<SysUser> getList() {
        List<SysUser> sysUsers = userMapper.selectList(null);
        return sysUsers;
    }

    /**
     * 根据用户id进行逻辑删除
     *
     * @param id
     * @return
     */
    public boolean logicDelete(String id) {
        int i = userMapper.deleteBatchIds(Arrays.asList(id));
        return i > 0 ? true : false;
    }

    public boolean deleteUser(String id) {
        int i = userMapper.deleteById(id);
        return false;
    }

    //根据map删除
    public int deleteMap(HashMap<String, Object> map) {
        int i = userMapper.deleteByMap(map);
        return i;
    }

    /**
     * 清理session
     */
    private void removeSession(String username) {
        //以下清除session缓存
        Session session = Jurisdiction.getSession();
        session.removeAttribute("Const.SESSION_USER");
        session.removeAttribute("USERNAME + Const.SESSION_ROLE_RIGHTS");
        session.removeAttribute("USERNAME + Const.SESSION_ALLMENU");
        session.removeAttribute("USERNAME + Const.SHIROSET");
        session.removeAttribute("Const.SESSION_USERNAME");
        session.removeAttribute("Const.SESSION_U_NAME");
        session.removeAttribute("Const.SESSION_USERROL");
        session.removeAttribute("Const.SESSION_RNUMBERS");
        session.removeAttribute("Const.SKIN");
    }
}
